from manim import *
from misc.character_design import *
from misc.character_design.pi_creature import SVGYan


class PIScene(PiCreatureScene):
    def construct(self):
        PiCreatureScene.setup(self, default_pi_creature_kwargs={"color": BLUE, "flip_at_start": False, "height": 1})
        self.blink()
        self.smile(1)
        self.look_at(Dot(1, 0, 0))
        self.say("笑笑", run_time=0.5)
        self.wait(0.5)
        self.smile(2)
        self.look_at(Dot(-1, 0, 0))
        self.say("哭哭", run_time=0.5)
        self.wait(0.5)
        self.smile(0)
        self.wait(0.5)


class YanScene(YanCreatureScene):
    def construct(self):
        pis = PiCreatureGroup(color=GREEN)
        # self.play(FlashThroughClass(pis))
        # self.add(Logo())
        lap = Laptop().next_to(np.array([2, 1, 0]))
        self.add(lap)
        eye = Eyes(lap, thing_to_look_at=pis)
        from misc.character_design.pi_creature import BabyPiCreature
        body_pi = BabyPiCreature()
        self.add(eye)
        self.add(body_pi)
        self.play(Blink(eye))
        self.add(Clock().next_to(np.array([-7, 1, 0])))
        yan = Yan().next_to(3*DOWN)
        self.add(yan)
        self.pi_creature_says(yan, "笑笑", run_time=0.5, bubble_kwargs={'height': 1, 'width': 2})
        self.pi_creature_says(yan, "哭哭", run_time=1, bubble_kwargs={'height': 1, 'width': 2})
        self.remove_bubble(yan)
        self.add(Yan().scale(0.3).next_to(3 * UL))
        self.add(Yan().scale(0.5).next_to(3*UP))
        small_yan = SmallYan().next_to(3*UR)
        self.add(small_yan)
        self.add(Yan().scale(2).next_to(3*DR))
        self.play(Emo(small_yan, 0.5))
        self.play(Emo(yan, 0.5))
        self.wait(1)
        self.play(Emo(yan, -0.5))
        self.play(Blink(yan))
        self.wait(1)
        self.play(yan.animate.move_to(UP))
        self.pi_creature_thinks(yan, "耶耶", run_time=0.5, bubble_kwargs={'height': 1, 'width': 2})
        self.pi_creature_thinks(yan, "棒棒", run_time=0.5, bubble_kwargs={'height': 1, 'width': 2})
        text = "sadasd"
        saying = PiCreatureSays(yan, text, bubble_kwargs={'height': 1, 'width': 2})
        # emo should be later by saying, conver to -1~1 by lost rate.
        emo = Emo(yan, 0.5)
        look = LookAt(yan, UR)
        self.play(saying, emo, look)
        self.remove_bubble(yan)
        self.wait(1)
        self.wait(1)


def bezier_line_b():
    p1 = np.array([-3, 1, 0])
    p1b = p1 + [1, 0, 0]
    p2 = np.array([3, -1, 0])
    p2b = p2 - [1, 0, 0]
    bezier1 = CubicBezier(p1b, p1b + 3 * RIGHT, p2b - 3 * RIGHT, p2b)
    return bezier1

def bezier_line_g():
    p1 = np.array([3, 1, 0])
    p1b = p1 - [1, 0, 0]
    p2 = np.array([-3, -1, 0])
    p2b = p2 + [1, 0, 0]
    bezier2 = CubicBezier(p1b, p1b + 3 * RIGHT, p2b - 3 * RIGHT, p2b)
    return bezier2


def hexagram_line():
    hexagram = Polygram(
        [[0, 2, 0], [-np.sqrt(3), -1, 0], [np.sqrt(3), -1, 0]],
        [[-np.sqrt(3), 1, 0], [0, -2, 0], [np.sqrt(3), 1, 0]],
    ).scale(0.5)
    return hexagram


def always_redraw(func, loot_at):
    mob = func(loot_at)
    mob.add_updater(lambda m: mob.become(func(loot_at)))
    return mob


class WelcomeYan(YanCreatureScene):
    def construct(self):
        bl = bezier_line_b()
        boy_yan = SVGYan(mode="plain", color=GREEN_A, height=2).next_to(bl.get_start())
        self.add(boy_yan)
        boy_yan.generate_target()
        self.play(MoveAlongPath(boy_yan, bl), run_time=2)
        boy_yan.target.change_mode(mode="dance").scale(1.5)
        change_mode = MoveToTarget(boy_yan)
        animation = AnimationGroup(MoveAlongPath(boy_yan, Line(boy_yan.get_center(), DOWN)), change_mode)
        self.play(animation, run_time=2)
        boy_yan.target.change_mode(mode="welcome")
        self.play(MoveToTarget(boy_yan))
        self.play(Blink(boy_yan))
        boy_yan.target.change_mode(mode="plain").scale(0.5)
        change_mode = MoveToTarget(boy_yan)
        self.play(AnimationGroup(MoveAlongPath(boy_yan, Line(boy_yan.get_center(), bl.get_start())), change_mode))

        bl = bezier_line_g()
        girl_yan = SVGYan(color=RED_A, height=2, flip_at_start=True).next_to(boy_yan, direction=RIGHT)
        self.add(girl_yan)
        self.play(FadeIn(girl_yan))
        girl_yan.generate_target()
        self.play(MoveAlongPath(girl_yan, bl), run_time=2)
        girl_yan.target.change_mode(mode="dance").scale(1.5)
        change_mode = MoveToTarget(girl_yan)
        animation = AnimationGroup(MoveAlongPath(girl_yan, Line(girl_yan.get_center(), DOWN)), change_mode)
        self.play(animation, run_time=2)
        girl_yan.target.change_mode(mode="welcome")
        self.play(MoveToTarget(girl_yan))
        self.play(Blink(girl_yan))
        girl_yan.target.change_mode(mode="plain").scale(0.5)
        change_mode = MoveToTarget(girl_yan)
        self.play(AnimationGroup(MoveAlongPath(girl_yan, Line(girl_yan.get_center(), bl.get_start())), change_mode))
        self.wait(0.5)

        movement = AnimationGroup(MoveAlongPath(boy_yan, Ellipse(width=4.0, height=2.0)),
                                  MoveAlongPath(girl_yan, Ellipse(width=3.0, height=3.0)), lag_ratio=0.1)
        self.play(movement, run_time=3)
        movement = AnimationGroup(MoveAlongPath(boy_yan, Ellipse(width=4.0, height=2.0)),
                                  MoveAlongPath(girl_yan, Ellipse(width=3.0, height=3.0)), lag_ratio=0.2)
        self.play(movement, run_time=3)


if __name__ == "__main__":
    with tempconfig({"quality": "medium_quality", "frame_height": 8., "frame_width": 8.,
                     "preview": True, "format": "gif", "transparent": False}):
        scene = WelcomeYan()
        scene.render()

